/*
* File: SmartFileMatcher.java
* Author: Daniel Rogers
* Created on Feb 29, 2008
*
*/
package gri.gridp.filematchers;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.io.File;
import gri.gridp.scripts.UnixScriptParser;
/**
* FileMatcher which allows parameters to be specified.
* These parameters are stored in a map and may be referenced
* in the match pattern. A pattern such as:
*
* $(inFile).txt
*
* Will replace "$(inFile)" with the value of the "inFile" parameter.
* Additionally, to deal with basic manipulations of file names extra
* parameters are automatically created when a parameter contains a
* period. If the parameter "inFile" has a value of "myfile.xml" the
* following parameters will be created:
*
* inFile.base = "myfile"
* inFile.ext = "xml"
*
* This allows expressions such as:
*
* $(inFile.base).*
*
* To match all files that have the base name of "inFile" but may have
* any extension.
*
* TODO: do we need more advanced manipulation? (.rstrip(), .lstrip()?)
*
* @author dan.rogers
*/
public class AdvancedFileMatcher implements FileMatcher {
String pattern;
Map params;
FileMatcher matcher;
boolean isDirty; //indicates a change to pattern or params has been made
// ----------------------------------------------------- Constructors
public AdvancedFileMatcher(String pattern, Map params) {
matcher = new WildcardFileMatcher(null);
this.params = params;
setPattern(pattern);
}
public AdvancedFileMatcher(String pattern) {
this(pattern, new HashMap());
}
public AdvancedFileMatcher(Map params) {
this(null, params);
}
// -------------------------------------------------------- Accessors
/**
* Sets the pattern for the matcher.
*/
public void setPattern(String pattern) {
this.pattern = pattern;
this.isDirty = true;
}
public String getPattern() {return this.pattern;}
/**
* Sets the parameter map
*/
public void setParameters(Map params) {
this.params = params;
this.isDirty = true;
}
//NOTE: This would allow alteration of the map without setting isDirty
//public Map getParameters() {return this.params;}
public void setParameter(String name, String value) {
params.put(name, value);
this.isDirty = true;
}
public String getParameter(String name) {
return (String)params.get(name);
}
// --------------------------------------------------- Implementation
public boolean matches(File file) {
if (this.isDirty)
updatePattern();
return matcher.matches(file);
}
/**
* Updates the pattern, calling evalPattern() to swap in the current
* set of parameters and passing the new pattern through to the matcher.
*/
protected void updatePattern() {
if (pattern == null)
matcher.setPattern(null);
else
matcher.setPattern(evalPattern(this.pattern));
this.isDirty = false;
}
/**
* Evaluates the given pattern, swapping in the current parameters.
* When parameter values contain a period new parameters named
* "[paramName].base" and "[paramName].ext" will also be created
* and swapped into the script. These correspond to the base name
* and extension of the given parameter value when it is interpreted
* as a file name.
*
* e.g.:
*
* if we have:
* inFile = "myfile.txt"
*
* we will get:
* inFile = "myfile.txt"
* inFile.base = "myfile"
* inFile.ext = "txt"
*
* The new parameters are only used here and do not affect the stored
* parameter map.
*/
protected String evalPattern(String pattern) {
Map newParams = new HashMap();
//copy all parameters:
newParams.putAll(this.params);
//add "name.base" and "name.ext" parameters for file's
// base name and extension
Iterator entries = params.entrySet().iterator();
Map.Entry entry;
while (entries.hasNext()) {
entry = (Map.Entry)entries.next();
String paramName = (String)entry.getKey();
String value = (String)entry.getValue();
int index = value.lastIndexOf(".");
if (index >= 0) {
String baseName = value.substring(0, index);
String ext = value.substring(index + 1);
newParams.put(paramName + ".base", baseName);
newParams.put(paramName + ".ext", ext);
}
}
String newPattern = new UnixScriptParser().setVariables(pattern, newParams);
System.out.println(newPattern);
return newPattern;
}
// -------------------------------------------------------- Test
public static void main(String [] args) {
/*
AdvancedFileMatcher matcher = new AdvancedFileMatcher("$(inFile).txt");
matcher.setParameter("inFile", "file2");
System.out.println(matcher.matches(new File("file2.txt")));
*/
/*
AdvancedFileMatcher matcher = new AdvancedFileMatcher("$(inFile.base).txt");
matcher.setParameter("inFile", "myfile.pdb");
System.out.println(matcher.matches(new File("myfile.txt")));
*/
AdvancedFileMatcher matcher = new AdvancedFileMatcher("$inFile");
matcher.setParameter("inFile", "myfile.pdb");
System.out.println(matcher.matches(new File("myfile.pdb")));
/*
AdvancedFileMatcher matcher = new AdvancedFileMatcher("file*");
System.out.println(matcher.matches(new File("file.txt")));
*/
}
}